/* Additional type traits */

#ifndef MC_TYPE_TRAITS_HPP
#define MC_TYPE_TRAITS_HPP

#include <cstddef> /* For __GLIBCXX__ */

/* TR1 header */
#ifdef __GLIBCXX__
	#include <tr1/type_traits>
#else
	#include <type_traits>
#endif

namespace memchart
{
	/* Tell if T is cv-qualified */
	template <typename T>
	struct is_cv_qualified : std::tr1::integral_constant<
			bool,
			std::tr1::is_const<T>::value || std::tr1::is_volatile<T>::value
		>
	{ };

	/* Tell if T is a pointer */
	template <typename T>
	struct is_pointer : std::tr1::integral_constant<
			bool,
			std::tr1::is_pointer<T>::value
				|| std::tr1::is_member_pointer<T>::value
		>
	{ };

	/* Tell if T is a pointer to object */
	template <typename T>
	struct is_object_pointer : std::tr1::integral_constant<
			bool,
			std::tr1::is_pointer<T>::value
				&& !std::tr1::is_function<
						typename std::tr1::remove_pointer<T>::type
					>::value
		>
	{ };

	/*
	 * Tell if we should display members of T separately instead of streaming
	 * T to an ostream
	 */
	template <typename T>
	struct show_members : std::tr1::false_type
	{ };

	#define MC_SHOW_MEMBERS(class) \
		namespace memchart \
		{ \
			template <> \
			struct show_members<class> : std::tr1::is_class<class> \
			{ }; \
		}
}

#endif /* MC_TYPE_TRAITS_HPP */
